package com.bjkcst.baselib.utils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * byte数据处理工具类
 */
public class ByteUtils {

    /**
     * 把原始数据分割成一个个的Byte
     *
     * @param data 接收到的一串数据
     * @return 分割后的字符串组（16进制）
     */
    public static List<String> GetBitList(String data) {
        return GetStrList(data, 2);
    }


    /**
     * 获取单独一位的BIT数据(0-7)
     *
     * @param hex      16进制的字符串数据
     * @param bitIndex 第几位
     * @return true=1 false=0
     */
    public static boolean GetOneBit(String hex, int bitIndex) {
        if (bitIndex < 0 || bitIndex > 7)
            return false;

        int data = Integer.parseInt(hex, 16);
        return (((data & ((int) (Math.pow(2, bitIndex)))) >> bitIndex) == 1);
    }

    /**
     * 把原始数据分割成一个个的Byte
     *
     * @param data 接收到的一串数据
     * @return 分割后的字符串组（16进制）
     */
    public static List<String> GetByteList(String data) {
        return GetStrList(data, 2);
    }

    /**
     * 把原始字符串分割成指定长度的字符串列表
     *
     * @param inputString 原始字符串
     * @param length      指定长度
     * @return
     */
    public static List<String> GetStrList(String inputString, int length) {
        int size = inputString.length() / length;
        if (inputString.length() % length != 0) {
            size += 1;
        }
        return GetStrList(inputString, length, size);
    }

    /**
     * 把原始字符串分割成指定长度的字符串列表
     *
     * @param inputString 原始字符串
     * @param length      指定长度
     * @param size        指定列表大小
     * @return
     */
    public static List<String> GetStrList(String inputString, int length, int size) {
        List<String> list = new ArrayList<>();
        for (int index = 0; index < size; index++) {
            String childStr = substring(inputString, index * length, (index + 1) * length);
            list.add(childStr);
        }
        return list;
    }

    /**
     * 分割字符串，如果开始位置大于字符串长度，返回空
     *
     * @param str 原始字符串
     * @param f   开始位置
     * @param t   结束位置
     * @return
     */
    public static String substring(String str, int f, int t) {
        if (f > str.length())
            return null;
        if (t > str.length()) {
            return str.substring(f);
        } else {
            return str.substring(f, t);
        }
    }

    /**
     * 单字节转换成十六进制字符串
     *
     * @param b byte数据
     * @return 十六进制字符 XX 一个字节 不足补零
     */
    public static String OneByteToHexString(byte b) {
        String sTemp = Integer.toHexString(0xFF & b);
        if (sTemp.length() < 2) sTemp = "0" + sTemp;
        return sTemp;
    }

    /**
     * 把单个字节转换成二进制字符串
     */
    public static String byteToBin(byte b) {
        String zero = "00000000";
        String binStr = Integer.toBinaryString(b & 0xFF);
        if (binStr.length() < 8) {
            binStr = zero.substring(0, 8 - binStr.length()) + binStr;
        }
        return binStr;
    }

    /**
     * 获取字节在内存中某一位的值，采用字符取值方式
     */
    public static Integer getBitByByte(byte b, int index) {
        if (index >= 8) {
            return null;
        }
        Integer val = null;
        String binStr = byteToBin(b);
        val = Integer.parseInt(String.valueOf(binStr.charAt(index)));
        return val;
    }

    /**
     * 两个十六进制转为十进制
     *
     * @param b1 十六进制低位
     * @param b2 十六进制高位
     * @return
     */
    public static int byteToInt(byte b1, byte b2) {
        int deci = (b1 | b2 << 8);
        return deci;
    }

    public static int hexStrToIntByWord(int b1, int b2) {
        int deci = (b1 | b2 << 8);
        return deci;
    }

    public static byte[] getBooleanArray(byte b) {
        byte[] array = new byte[8];
        for (int i = 7; i >= 0; i--) {
            array[i] = (byte) (b & 1);
            b = (byte) (b >> 1);
        }
        return array;
    }

    //高字节在前，低字节在后  转两个字节
    public static int ByteToInt(byte[] array) {
        int value;
        value = (int) (((array[0]) << 8) | ((array[1] & 0xFF)));
        return value;
    }

    public static int ByteToUnsignedInt(byte[] array) {
        int value;
        value = (int) (((array[0] & 0xFF) << 8) | ((array[1] & 0xFF)));
        return value;
    }

    //低在前,高在后  转两个字节
    public static int ByteToIntRight(byte[] array) {
        int value;
        value = (int) (((array[1]) << 8) | (array[0] & 0xFF));
        //value = (int) (((array[0] & 0xFF) << 8) | (array[1] & 0xFF));
        return value;
    }


    /*
    得出byte中 第一个( bit不为0 ) 的下标
     */
    public static int getBitIndex_1(byte b) {
        StringBuilder stringBuilder;
        byte[] booleanArray = getBooleanArray(b);
        String s = Arrays.toString(booleanArray);
        String substring = s.substring(1, 23);
        String[] split = substring.split(", ");
        stringBuilder = new StringBuilder();
        for (String s1 : split) {
            stringBuilder.append(s1);
        }
        int index = stringBuilder.toString().indexOf("1");
        stringBuilder = null;
        return index;
    }

    public static String ByteToString(byte bdata) {
        String sTemp = Integer.toString(bdata);
        if (sTemp.length() < 2)
            sTemp = "0" + sTemp;
        return sTemp;
    }

    public static int hexStrToIntByWord(String dateH, String dateL) {
        return Integer.parseInt(dateH + dateL, 16);
    }


    //四字节相加，按顺序
    public static int hexStrToIntByWord(String date4, String date3, String date2, String date1) {
        //  return  Integer.parseInt(date4,16) +  Integer.parseInt(date3,16) +  Integer.parseInt(date2,16) +  Integer.parseInt(date1,16);
        return Integer.parseInt((date4 + date3 + date2 + date1), 16);
    }


    /**
     * add by lxsynl 20201123
     * 用于将byte[]转换成int，最大适用于长度为4的byte[]
     *
     * @param data 要转换的byte[]
     * @param n    数组元素个数
     * @return
     */
    public static int byte2int(byte[] data, int n) {
        switch (n) {
            case 1:
                return (int) data[0];
            case 2:
                return (int) (data[0] & 0xff) | (data[1] << 8 & 0xff00);
            case 3:
                return (int) (data[0] & 0xff) | (data[1] << 8 & 0xff00) | (data[2] << 16 & 0xff0000);
            case 4:
                return (int) ((int) data[3] & 0xff) | ((int) data[2] << 8 & 0xff00) | ((int) data[1] << 16 & 0xff0000)
                        | ((int) data[0] << 24 & 0xff000000);
            default:
                return 0;
        }
    }

    public static byte[] shortToByte(short number) {
        byte[] b = new byte[2];
        b[0] = (byte) (number >> 8);
        b[1] = (byte) (number >> 0);
        return b;
    }

    /**
     * byte数组转 4字节int
     *
     * @param array
     * @return
     */
    public static int byteArrayToLittleInt(byte[] array) {
        int result = 0;
        if (array.length == 4) {
            int a = (array[0] & 0xff);
            int b = (array[1] & 0xff) << 8;
            int c = (array[2] & 0xff) << 16;
            int d = (array[3] & 0xff) << 24;
            result = a | b | c | d;
        }
        return result;
    }

    /**
     * byte数组转 4字节int 相当于int 直接16进制直接转10进制
     *
     * @param array
     * @return
     */
    public static int byteArrayToBigInt(byte[] array) {
        int result = 0;
        if (array.length == 4) {
            int a = (array[3] & 0xff);
            int b = (array[2] & 0xff) << 8;
            int c = (array[1] & 0xff) << 16;
            int d = (array[0] & 0xff) << 24;
            result = a | b | c | d;
        }
        return result;
    }

    /**
     * byte数组转 4字节float
     *
     * @param bytes
     * @return
     */
    public static float byteArrayToFloat(byte[] bytes) {
        int result = 0;
        if (bytes.length == 4) {
            int a = (bytes[0] & 0xff);
            int b = (bytes[1] & 0xff) << 8;
            int c = (bytes[2] & 0xff) << 16;
            int d = (bytes[3] & 0xff) << 24;
            result = a | b | c | d;
        }
        return Float.intBitsToFloat(result);
    }

}
